﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.ComponentModel;

namespace APRESS.TimeTracker.ViewModels
{
    public abstract class ObservableObject<T> : INotifyPropertyChanged
    {
        #region Implementation of INotifyProperyChanged

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        public void OnPropertyChanged(Expression<Func<T, object>> property)
        {
            var properyName = GetPropertyName(property);
            if (PropertyChanged != null)
            {
                var handler = PropertyChanged;
                handler(this, new PropertyChangedEventArgs(properyName));
            }
        }

        private string GetPropertyName(Expression<Func<T, object>> expression)
        {
            if (expression == null)
            {
                throw new ArgumentException("propertyExpression");
            }
            var memberExpression = expression.Body as MemberExpression;
            if (memberExpression == null)
            {
                throw new ArgumentException("The expression is not a memebr access expression.", "expression");
            }
            var property = memberExpression.Member as PropertyInfo;
            if (property == null)
            {
                throw new ArgumentException("The member access expression does not access a propery.", "expression");
            }
            var getMethod = property.GetGetMethod(true);
            if (getMethod.IsStatic)
            {
                throw new ArgumentException("The references property is a static propery.", "expression");
            }
            return memberExpression.Member.Name;
        }

    }
}
